package com.hd.trans.network

import android.annotation.SuppressLint
import com.franmontiel.persistentcookiejar.ClearableCookieJar
import com.franmontiel.persistentcookiejar.PersistentCookieJar
import com.franmontiel.persistentcookiejar.cache.SetCookieCache
import com.franmontiel.persistentcookiejar.persistence.SharedPrefsCookiePersistor
import com.hd.trans.TranslationInterior
import com.hd.trans.network.apiService.AiTransService
import com.hd.trans.network.apiService.ApiService
import com.hd.trans.network.apiService.ApiV4Service
import com.hd.trans.network.apiService.CloudControlService
import com.hd.trans.network.apiService.RomaService
import com.hd.trans.network.apiService.TextToSpeechService
import com.hd.trans.network.apiService.TransitionNewApi
import com.hd.trans.network.apiService.UniversalService
import com.hd.trans.network.apiService.UrlConstant
import com.hd.trans.network.apiService.V4ApiService
import com.hd.trans.network.factory.CustomMoshiConverterFactory
import com.hd.trans.ui.base.AppContextProvider
import com.hd.trans.utils.SSLCertificate
import okhttp3.Cache
import okhttp3.OkHttpClient
import okhttp3.logging.HttpLoggingInterceptor
import retrofit2.Retrofit
import retrofit2.adapter.rxjava2.RxJava2CallAdapterFactory
import retrofit2.converter.gson.GsonConverterFactory
import retrofit2.converter.moshi.MoshiConverterFactory
import retrofit2.converter.scalars.ScalarsConverterFactory
import java.io.File
import java.security.cert.CertificateException
import java.security.cert.X509Certificate
import java.util.concurrent.TimeUnit
import javax.net.ssl.HostnameVerifier
import javax.net.ssl.X509TrustManager

object ApiServiceManager {

    private const val CONNECT_TIMEOUT: Long = 15L
    private const val READ_TIMEOUT: Long = 30L
    private const val WRITE_TIMEOUT: Long = 30L
    //okHttpBuilder
    private var okHttpBuilder: OkHttpClient.Builder = OkHttpClient.Builder()
    private var translationBuilder: OkHttpClient.Builder = OkHttpClient.Builder()
    //声明日志类
    private val httpLoggingInterceptor = HttpLoggingInterceptor().apply {
        //设定日志级别
        setLevel(HttpLoggingInterceptor.Level.BODY)
    }

    /**
     * 新翻译接口
     */
    val transitionNewApi: TransitionNewApi by lazy {
        Retrofit.Builder()
            .client(translationBuilder.build())
            .addConverterFactory(ScalarsConverterFactory.create()) //直接处理原始响应内容，添加顺序放置首位。针对接口Call<String> createTask()
            .addConverterFactory(GsonConverterFactory.create()) //json转换成JavaBean
            .addCallAdapterFactory(RxJava2CallAdapterFactory.create())
            .baseUrl(UrlConstant.getTranslationApiUrl())
            .build()
            .create(TransitionNewApi::class.java)
    }

    val apiService: ApiService by lazy {
        Retrofit.Builder()
            .client(okHttpBuilder.build())
            .addConverterFactory(GsonConverterFactory.create()) //json转换成JavaBean
            .addCallAdapterFactory(RxJava2CallAdapterFactory.create())
            .baseUrl(UrlConstant.getBaseUrl())
            .build()
            .create(ApiService::class.java)
    }

    val romaService: RomaService by lazy {
        val builder = OkHttpClient.Builder()
        if (TranslationInterior.isDebug()) {
            builder.addInterceptor(httpLoggingInterceptor)
        }
        builder
            .addInterceptor(RecognitionInterceptor())
            .addInterceptor(HeaderInterceptor(true))
            .connectTimeout(30, TimeUnit.SECONDS)
            .readTimeout(30, TimeUnit.SECONDS)
            .writeTimeout(30, TimeUnit.SECONDS)

        Retrofit.Builder()
            .client(builder.build())
            .baseUrl(UrlConstant.getTranslationApiUrl())
            .addConverterFactory(CustomMoshiConverterFactory.create())
            .build()
            .create(RomaService::class.java)
    }

    val apiV4Service: ApiV4Service by lazy {
        val builder = OkHttpClient.Builder()
        if (TranslationInterior.isDebug()) {
            builder.addInterceptor(httpLoggingInterceptor)
        }
        builder
            .addInterceptor(RecognitionInterceptor())
            .addInterceptor(HeaderInterceptor(true))
            .connectTimeout(30, TimeUnit.SECONDS)
            .readTimeout(30, TimeUnit.SECONDS)
            .writeTimeout(30, TimeUnit.SECONDS)

        Retrofit.Builder()
            .client(builder.build())
            .baseUrl(UrlConstant.getV4ApiUrl())
            .addConverterFactory(CustomMoshiConverterFactory.create())
            .build()
            .create(ApiV4Service::class.java)
    }

    val universalService: UniversalService by lazy {
        val builder = OkHttpClient.Builder()
        if (TranslationInterior.isDebug()) {
            builder.addInterceptor(httpLoggingInterceptor)
        }
        builder
            .addInterceptor(HeaderInterceptor(true))
            .connectTimeout(30, TimeUnit.SECONDS)
            .readTimeout(30, TimeUnit.SECONDS)
            .writeTimeout(30, TimeUnit.SECONDS)

        Retrofit.Builder()
            .client(builder.build())
            .baseUrl(UrlConstant.getV4ApiUrl())
            .addConverterFactory(MoshiConverterFactory.create())
            .build()
            .create(UniversalService::class.java)
    }

    val v4ApiService: V4ApiService by lazy {
        Retrofit.Builder()
            .client(okHttpBuilder.build())
            .addConverterFactory(GsonConverterFactory.create()) //json转换成JavaBean
            .addCallAdapterFactory(RxJava2CallAdapterFactory.create())
            .baseUrl(UrlConstant.getV4ApiUrl())
            .build()
            .create(V4ApiService::class.java)
    }

    /**
     * ttsService
     */
    val ttsService: TextToSpeechService by lazy {
        Retrofit.Builder()
            .client(okHttpBuilder.build())
            .addConverterFactory(GsonConverterFactory.create()) //json转换成JavaBean
            .addCallAdapterFactory(RxJava2CallAdapterFactory.create())
            .baseUrl(UrlConstant.getTtsUrl())
            .build()
            .create(TextToSpeechService::class.java)
    }

    /**
     * 云控
     */
    val cloudControlService: CloudControlService by lazy {
        Retrofit.Builder()
            .client(okHttpBuilder.build())
            .addConverterFactory(GsonConverterFactory.create()) //json转换成JavaBean
            .addCallAdapterFactory(RxJava2CallAdapterFactory.create())
            .baseUrl(UrlConstant.getCloudServiceUrl())
            .build()
            .create(CloudControlService::class.java)
    }

    /**
     * AI翻译
     */
    val aiTransService: AiTransService by lazy {
        //不要添加作用于response的Interceptor，如日志打印，否则会阻塞SSE
        val httpClient = OkHttpClient.Builder()
            //.addInterceptor(httpLoggingInterceptor)
            .addInterceptor(HeaderInterceptor(false, true))
            .retryOnConnectionFailure(true)
            .connectTimeout(CONNECT_TIMEOUT, TimeUnit.SECONDS)
            .readTimeout(180L, TimeUnit.SECONDS) //读取超时时间 180秒=3分钟
            .writeTimeout(WRITE_TIMEOUT, TimeUnit.SECONDS) //解决证书有效期的问题
            .sslSocketFactory(
                SSLCertificate.SSLSocketFactorygetSSLSocketFactory(),
                @SuppressLint("CustomX509TrustManager")
                object : X509TrustManager {
                    @SuppressLint("TrustAllX509TrustManager")
                    @Throws(CertificateException::class)
                    override fun checkClientTrusted(x509Certificates: Array<X509Certificate>, s: String) {}

                    @SuppressLint("TrustAllX509TrustManager")
                    @Throws(CertificateException::class)
                    override fun checkServerTrusted(x509Certificates: Array<X509Certificate>, s: String) {}

                    override fun getAcceptedIssuers(): Array<X509Certificate?> {
                        return arrayOfNulls(0)
                    }
                })
            .hostnameVerifier(HostnameVerifier { hostname, session ->
                true //信任host
            })
            .retryOnConnectionFailure(true)//错误重连
            .build()

        Retrofit.Builder()
            .client(httpClient)
            .baseUrl(UrlConstant.getV4ApiUrl())
            .addConverterFactory(GPTConverterFactory.create()) //SSE解析工厂
            .addCallAdapterFactory(RxJava2CallAdapterFactory.create())
            .build()
            .create(AiTransService::class.java)
    }

    init {
        initOkHttpBuilder()
        initTranslationBuilder()
    }

    private fun initOkHttpBuilder() {
        if (TranslationInterior.isDebug()) {
            okHttpBuilder.addInterceptor(httpLoggingInterceptor)
        }
        okHttpBuilder.addInterceptor(HeaderInterceptor(true))
        /**
         * 配置缓存和Cookie
         */
        if (AppContextProvider.getContext() != null) {
            val cookieJar: ClearableCookieJar = PersistentCookieJar(
                SetCookieCache(), SharedPrefsCookiePersistor(
                    AppContextProvider.getContext()
                )
            )
            val cache = Cache(
                File(AppContextProvider.getContext().cacheDir, "HttpCache"),
                (1024 * 1024 * 100).toLong()
            )
            okHttpBuilder.cache(cache)
            okHttpBuilder.cookieJar(cookieJar)
        }

        /**
         * 设置超时和重新连接
         */
        okHttpBuilder.connectTimeout(CONNECT_TIMEOUT, TimeUnit.SECONDS)
        okHttpBuilder.readTimeout(WRITE_TIMEOUT, TimeUnit.SECONDS)
        okHttpBuilder.writeTimeout(READ_TIMEOUT, TimeUnit.SECONDS)
        //错误重连
        okHttpBuilder.retryOnConnectionFailure(true)
    }

    private fun initTranslationBuilder() {
        if (TranslationInterior.isDebug()) {
            translationBuilder.addInterceptor(httpLoggingInterceptor)
        }
        translationBuilder
            .addInterceptor(HeaderInterceptor(false))
            .retryOnConnectionFailure(true)
            .connectTimeout(CONNECT_TIMEOUT, TimeUnit.SECONDS)
            .readTimeout(WRITE_TIMEOUT, TimeUnit.SECONDS)
            .writeTimeout(READ_TIMEOUT, TimeUnit.SECONDS)
            //解决证书有效期的问题
            .sslSocketFactory(
                SSLCertificate.SSLSocketFactorygetSSLSocketFactory(),
                @SuppressLint("CustomX509TrustManager")
                object : X509TrustManager {
                    @SuppressLint("TrustAllX509TrustManager")
                    @Throws(CertificateException::class)
                    override fun checkClientTrusted(x509Certificates: Array<X509Certificate>, s: String) {}

                    @SuppressLint("TrustAllX509TrustManager")
                    @Throws(CertificateException::class)
                    override fun checkServerTrusted(x509Certificates: Array<X509Certificate>, s: String) {}

                    override fun getAcceptedIssuers(): Array<X509Certificate?> {
                        return arrayOfNulls(0)
                    }
                })
            .hostnameVerifier { hostname, session ->
                true //信任所有host
            }
            .retryOnConnectionFailure(true)//错误重连
    }

}